// import { createStore } from 'vuex'
// ↑官方的
// ↓我们的
import { createStore } from '@/vuex'


function customPlugin(store){
  const local = localStorage.getItem('VUEX:STATE');
  if (local) {
    store.replaceState(JSON.parse(local));
  }

  store.subscribe((mutation/*{type, payload}*/,state) => { //每当状态发生变化 (调用mutation的时候 就会执行此回调)
    localStorage.setItem('VUEX:STATE', JSON.stringify(state));
  });
}

const store = createStore({
  strict:true, //设置true后 不能从外部直接修改 store.state, 参看 src/App.vue case1: 严格模式下会报错

  // 会按照注册的顺序依次执行
  // 执行的时候会把store传进来
  plugins:[
    customPlugin
  ],

  state: { // 组件中的data
    count: 1
  },

  getters: { // vuex4 他并没有实现计算属性的功能
    double(state){
      return state.count * 2;
    }
  },

  mutations: { // 可以更改状态 必须是同步更改的
    add(state,payload){
      state.count += payload;
    }
  },

  actions: { // 可以调用其他action 或则调用mutation
    asyncAdd({commit},payload){
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          commit('add', payload);
          resolve();
        }, 1000);
      });
    }
  },

  modules: {
    aCount: {
      namespaced:true, //这样 如果 $store.commit('add',1) 就不会修改子模块的状态了 (默认namespaced不设置为true, 是会的) // 此时想要修改子模块的state 必须带上命名空间 $store.commit('aCount/add',1) // 另外如果它下的子模块没有带namespaced, 那么触发它 也会触发它下的子模块的同名方法
      state: {count:0},
      mutations: {
        add(state,payload){
          state.count += payload;
        }
      },
      modules: {
        cCount: {
          namespaced:true,
          state: {count:0},
          mutations: {
            add(state,payload){
              state.count += payload;
            }
          }
        }
      }
    },
    bCount: {
      namespaced:true,
      state: {count:0},
      mutations: {
        add(state,payload){
          state.count += payload;
        }
      }
    }
  }
})

store.registerModule(['aCount','dCount']/*←← 如果只有一层,可以是字符串形式'myModule'*/,{
  namespaced: true,
  state: {
    count: 0
  },
  mutations: {
    add(state, payload) {
      state.count += payload;
    }
  }
})

export default store;
